package com.zam.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zam.comment.Result;
import com.zam.mapper.SysFileMapper;
import com.zam.pojo.SysFile;
import com.zam.service.ISysFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zam.comment.Constants.CODE_200;
import static com.zam.comment.Constants.CODE_600;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zam
 * @since 2023-12-17
 */
@Service
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements ISysFileService {

    @Autowired
    private SysFileMapper sysFileMapper;

    @Value("${file.upload.path}")
    private String fileUploadPath;

    @Override
    public Map<String, Object> saveFile(MultipartFile file, HttpServletRequest request) throws IOException {
        Map<String, Object> map = new HashMap<>();


        String originalFilename = file.getOriginalFilename();// 文件名
        String type = FileUtil.extName(originalFilename); // 后缀名
        int size = (int) (file.getSize() / 1024);// 文件大小

        File originalFilepath = new File(fileUploadPath); // 上传路径
        // 判断路径是否存在
        if (!originalFilepath.exists()) {
            originalFilepath.mkdirs();
        }

        String uuid = IdUtil.fastSimpleUUID(); // 文件名唯一标识
        String FileUUID = uuid + StrUtil.DOT + type;
        File originalFile = new File(fileUploadPath + FileUUID);
        //不管是否存在数据，都先保存数据
        file.transferTo(originalFile); // 上传文件,获取到的文件存储到磁盘目录中(复制)

        //通过MD5查询数据（统一文件md5校验码一样）
        String md5 = SecureUtil.md5(originalFile);
        //查询数据库中是否存在该数据，包括逻辑删除的数据（自己编写的sql语句）
        List<SysFile> sysFiles = sysFileMapper.myFindAll(md5, null);


        String url = "";
        if (sysFiles.size() == 0) {
            //说明数据库中没有该文件数据
            // 生成对应下载文件的请求路径，保存到数据库中
            url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/file/download/" + FileUUID;
            map.put("url",url);
        } else {
            //说明数据库中有该文件数据
            //删除原文件
            originalFile.delete();
            //查询文件名称是否也相同（自己编写的sql语句）
            List<SysFile> sysFiles2 = sysFileMapper.myFindAll(md5, originalFilename);
            if (sysFiles2.size() != 0) {
                //todo 如果名称也一样，直接返回
                LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SysFile::getMd5, md5).eq(SysFile::getName, originalFilename);
                //由于使用了mp，逻辑删除的代码不会查询出来
                SysFile sysFile = sysFileMapper.selectOne(queryWrapper);
                if (BeanUtil.isEmpty(sysFile)) {
                    //执行到这，说明该数据已经被逻辑删除
                    Integer id = sysFiles.get(0).getId();
                    //将数据恢复
                    String isDelete = "0";
                    // 保存到数据库(自己编写的sql语句)
                    sysFileMapper.myUpdateById(id, isDelete);
                    String url1 = sysFileMapper.myGetUrl(id);
                    map.put("url",url1);
                    map.put("code",CODE_200);
                    return map;
                }
                //执行到这，说明该数据没有被逻辑删除,页面中有该文件
                map.put("code",CODE_600);
                map.put("url",sysFile.getUrl());
                return map;
            }
            //名称不一样，随便获取一个对象的url,并赋值
            url = sysFiles.get(0).getUrl();
            map.put("url",url);
        }
        // 保存到数据库
        SysFile sysFile = new SysFile();
        sysFile.setName(originalFilename);
        sysFile.setType(type);
        sysFile.setSize(size);
        sysFile.setUrl(url);
        sysFile.setMd5(md5);

        sysFileMapper.insert(sysFile);
        map.put("code",CODE_200);



        return map;
    }
}
